 /**
 * Description: 实施资料管理
 * @author:jacky
 * @since:1.0.0
 *
 * Modification History:
 * Date         Author      Version     Description
 * ------------------------------------------------------------------
 * 2018-05-02   jacky       1.0.0     Initial
 */
package com.metro.demo.material.controller;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.w3c.dom.ls.LSInput;

import com.github.pagehelper.PageInfo;
import com.metro.core.annotation.BusinessDesc;
import com.metro.core.page.Page;
import com.metro.core.vo.JsonResult;
import com.metro.core.vo.QueryParams;
import com.metro.core.vo.ResultCode;
import com.metro.core.vo.inf.IResult;
import com.metro.demo.common.beans.constant.PropertiesEnum;
import com.metro.demo.common.beans.vo.WebUserInfo;
import com.metro.demo.material.beans.vo.BizMaterialManage;
import com.metro.demo.material.service.inf.IBizMaterialManageService;
import com.metro.demo.web.controller.BaseController;
 /**
 * 实施资料管理<br>
 *
 * @author:jacky
 * @since:1.0.0
 * @version [1.0.0, 2018-05-02]
 */
@Controller
@RequestMapping("/bizMaterialManage")
public class BizMaterialManageController extends BaseController {
    //菜单编码
    private static final String menuCode = "BIZ_MATERIAL_MANAGE";
    //模块描述
    private static final String MODULE_DESC = "实施资料管理";
    @Autowired
    private IBizMaterialManageService bizmaterialmanageService;
    @Override
    protected String getViewDir() {
        return "material/";
    }
    
    /**
     * 去查询实施资料管理
     * 
     * @param bizmaterialmanage 实施资料管理页面表单对象
     * @param page 分页配置
     * @return 结果视图
     * @author jacky
     * @since [1.0.0]
     * @version [1.0.0, 2018-05-02]
     */
    @BusinessDesc(ModuleDesc = MODULE_DESC, MethodDesc = "查询实施资料管理列表")
    @RequiresPermissions(menuCode + ":view")
    @SuppressWarnings("all")
    @RequestMapping(value = "list/{code}", method = {RequestMethod.GET,RequestMethod.POST})
    public ModelAndView list(@PathVariable String code,BizMaterialManage bizmaterialmanage) {
        ModelAndView mav = new ModelAndView();
        //获取用户的登录信息
    	Subject currentUser = SecurityUtils.getSubject();
        WebUserInfo userInfo  = (WebUserInfo)currentUser.getPrincipal();
        //获取登录用户名
        String username = userInfo.getUserName();
        try {
        	if(code.equals("1")) {
        		mav.setViewName(getView("bizmaterialmanage_list"));
        	}else{
        		mav.setViewName(getView("bizmaterialbackmanage_list"));
        	}
            mav.addObject("searchEntity", bizmaterialmanage);
            mav.addObject("username", username);
            mav.addObject("type", code);
        } catch (Exception ex) {
            log.error("查询实施资料管理出错", ex);
            mav.addObject("ex", ex);
            mav.setViewName("/commons/error/error");
        }
        return mav;
    }

    /**
     * 查询实施资料管理
     *
     * @param bizmaterialmanage 实施资料管理页面表单对象
     * @param page 分页配置
     * @return 结果视图
     * @author jacky
     * @since [1.0.0]
     * @version [1.0.0, 2018-05-02]
     */
    @BusinessDesc(ModuleDesc = MODULE_DESC, MethodDesc = "查询实施资料管理列表")
    @RequiresPermissions(menuCode + ":view")
    @SuppressWarnings("all")
    @RequestMapping(value = "dolist", method = {RequestMethod.GET,RequestMethod.POST})
    @ResponseBody
    public JsonResult dolist(BizMaterialManage bizmaterialmanage, Page page, QueryParams<BizMaterialManage> queryParams) {
        JsonResult jr = new JsonResult();
        try {
            queryParams.setPaging(page);
            queryParams.setEntity(bizmaterialmanage);
            PageInfo<BizMaterialManage> pageInfo = bizmaterialmanageService.queryForPage(queryParams);
            jr.setData(pageInfo);
            jr.setResult(ResultCode.SUCCESS);
        } catch (Exception ex){
            log.error("查询实施资料管理出错",ex);
            jr.setResult(ResultCode.ERROR);
        }
        return jr;
    }

    /**
     * 删除实施资料管理
     *
     * @param id 实施资料管理页面表单对象唯一标识
     * @param request 请求对象
     * @return 结果视图
     * @author jacky
     * @since [1.0.0]
     * @version [1.0.0, 2018-05-02]
     */
    @BusinessDesc(ModuleDesc = MODULE_DESC, MethodDesc = "删除实施资料管理")
    @RequiresPermissions(menuCode + ":delete")
    @RequestMapping(value = "delete", method = { RequestMethod.POST })
    @ResponseBody
    public JsonResult delete(BizMaterialManage entity){
        JsonResult jr = new JsonResult();
        try {
            log.debug("删除实施资料管理id={}",entity.getCode());
            IResult codeMsg = bizmaterialmanageService.deleteByCode(entity);
            jr.setResult(codeMsg);
        } catch (Exception ex) {
            log.error("删除实施资料管理出错", ex);
            jr.setResult(ResultCode.ERROR);
        }
        return jr;
    }
    
    /**
     * 图片查看
     * 
     * @param id 实施资料管理页面表单对象唯一标识
     * @return 结果视图
     * @author jacky
     * @since [1.0.0]
     * @version [1.0.0, 2018-05-02]
     */
    @BusinessDesc(ModuleDesc = MODULE_DESC, MethodDesc = "去查看实施资料管理详情")
    @RequiresPermissions(menuCode + ":view")
    @RequestMapping(value = "info/{code}", method = { RequestMethod.GET })
    public ModelAndView info(@PathVariable String code) {
        ModelAndView mav= new ModelAndView(); 
        BizMaterialManage entity = new BizMaterialManage();
        try {
        	List<BizMaterialManage>  entitys = bizmaterialmanageService.getBycode(code);
            mav.addObject("list",entitys);
            mav.setViewName(getView("bizmaterialmanage_show"));
        } catch (Exception ex) {
            log.error("查看实施资料管理出错", ex);
        }
        return mav;
        
    }
    //新增页面跳转
    @RequestMapping(value = "add/{code}", method = RequestMethod.GET)
    public ModelAndView batchImportForm(@PathVariable String code) {
        ModelAndView mav = new ModelAndView();
        if(code.equals("1")) {
        	 mav.setViewName(getView("fileInput"));
        }else {
        	 mav.setViewName(getView("backfileInput"));
        }
       
        return mav;
    }
    
    //图片再新增页面跳转
    @RequestMapping(value = "batchUpload/{code}/{name}", method = RequestMethod.GET)
    public ModelAndView batchUpload(@PathVariable String code,@PathVariable String name) {
        ModelAndView mav = new ModelAndView();
        mav.addObject("code",code);
        mav.addObject("name",name);
        mav.setViewName(getView("imageInput"));
        return mav;
    }
    //多图上传
    @RequestMapping(value = "/uploadMultipleImage", method = RequestMethod.POST, produces = "application/json;charset=utf8")
    @ResponseBody
    public JsonResult uploadMultipleFileHandler(@RequestParam("file") MultipartFile[] files,HttpServletRequest request) throws IOException {
    	JsonResult jr = new JsonResult();
    	ArrayList<Integer> arr = new ArrayList<>();
    	//获取用户的登录信息
    	Subject currentUser = SecurityUtils.getSubject();
        WebUserInfo userInfo  = (WebUserInfo)currentUser.getPrincipal();
        //获取登录用户名
        String username = userInfo.getUserName();
        //获取传入的code和name
        String code=request.getParameter("code");
        String name=request.getParameter("name");
        //如果前台没有经销商代码 直接返回
        if(StringUtils.isBlank(code)) {
        	return jr;
        }
        //遍历接收到的图片
        for (int i = 0; i < files.length; i++) {
            MultipartFile file = files[i]; 
            //获取系统文件上传根路径
            String dir = PropertiesEnum.getPropertyValue(PropertiesEnum.FILE_UPLOAD_ROOT)+"/implMaterial/image/"+code;
            //如果路径不存在 则新建
            File rootFile = new File(dir);
            if(!rootFile.exists()){  
            	rootFile.mkdirs();  
            }
            
            if (!file.isEmpty()) {
                InputStream in = null;
                OutputStream out = null;
                //获取文件名
                String fileName=file.getOriginalFilename();
                try {
                    String path = dir +"/"+ fileName;
                    File serverFile = new File(path);
                    in = file.getInputStream();
                    out = new FileOutputStream(serverFile);
                    byte[] b = new byte[1024];
                    int len = 0;
                    while ((len = in.read(b)) > 0) {
                        out.write(b, 0, len);
                    }
                    out.close();
                    in.close();
                    //设置存入数据库的路径
                    String savePath = "/implMaterial/image/"+code+"/" + fileName;
                    //经销商号码、名称、路径保存到数据库
                    BizMaterialManage entity = new BizMaterialManage();
                    entity.setCode(code);
                    entity.setName(name);
                    entity.setUploadPerson(username);
                    entity.setType("1");
                    entity.setImagePath(savePath);
                    //保存文件路径到数据库
                    IResult res = bizmaterialmanageService.save(entity);
                    jr.setResult(res);
                } catch (Exception e) {
                    arr.add(i);
                } finally {
                    if (out != null) {
                        out.close();
                        out = null;
                    }

                    if (in != null) {
                        in.close();
                        in = null;
                    }
                }
            } else {
                arr.add(i);
            }
        }
        return jr;
    }
    
    /**
     * 校验经销商代码是否重复
     * @param code
     * @return
     */
    @BusinessDesc(ModuleDesc = MODULE_DESC, MethodDesc = "校验经销商代码是否重复")
    @RequiresPermissions(menuCode + ":view")
    @SuppressWarnings("all")
    @RequestMapping(value = "checkCode", method = {RequestMethod.GET,RequestMethod.POST})
    @ResponseBody
    public JsonResult checkCode(String code,String type) {
        JsonResult jr = new JsonResult();
        //查询代码
        IResult res = bizmaterialmanageService.checkCode(code,type);
        String resultCode = res.getCode();
       	if ( resultCode.equals(ResultCode.DUPLICATE_KEY.getCode())) {
           	 jr.setResult(ResultCode.ERROR);
           	 jr.setMsg("经销商代码"+code+"已存在，请重新输入");
             log.debug("经销商代码已存在【{}】", resultCode);
       	}else {
       		jr.setResult(ResultCode.SUCCESS);
       	}    
        return jr;
    }
    
    
    //文件上传
    @RequestMapping(value = "/uploadMultipleFile", method = RequestMethod.POST, produces = "application/json;charset=utf8")
    @ResponseBody
    public JsonResult uploadMultipleFile(@RequestParam("file") MultipartFile[] files,HttpServletRequest request) throws IOException {
    	JsonResult jr = new JsonResult();
    	ArrayList<Integer> arr = new ArrayList<>();
    	//获取用户的登录信息
    	Subject currentUser = SecurityUtils.getSubject();
        WebUserInfo userInfo  = (WebUserInfo)currentUser.getPrincipal();
        //获取登录用户名
        String username = userInfo.getUserName();
        //遍历接收到的文件
        for (int i = 0; i < files.length; i++) {
            MultipartFile file = files[i]; 
            if (!file.isEmpty()) {
                InputStream in = null;
                OutputStream out = null;
                //获取文件名
                String fileName=file.getOriginalFilename();
                String names[];
                String code ;
                String name ="" ;
                names = fileName.split("-");
                if(names != null && names.length >3) {
	                //获取经销商代码
	                code = names[3];
	                //判断code是否存在
	                String type = "2";
	                IResult res = bizmaterialmanageService.checkCode(code,type);
	                String resultCode = res.getCode();
	               	if ( resultCode.equals(ResultCode.DUPLICATE_KEY.getCode())) {
	                   	 continue;
	               	}
	                //获取店名
	                name = names[2];
                }else {
                	code="文件名格式错误"+new java.text.SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
                }
                try {
                	
                	//获取系统文件上传根路径
                    String dir = PropertiesEnum.getPropertyValue(PropertiesEnum.FILE_UPLOAD_ROOT)+"/implMaterial/file/"+code;
                    //如果路径不存在 则新建
                    File rootFile = new File(dir);
                    if(!rootFile.exists()){  
                    	rootFile.mkdirs();  
                    }
                    String path = dir+"/"+ fileName;
                    File serverFile = new File(path);
                    in = file.getInputStream();
                    out = new FileOutputStream(serverFile);
                    byte[] b = new byte[1024];
                    int len = 0;
                    while ((len = in.read(b)) > 0) {
                        out.write(b, 0, len);
                    }
                    out.close();
                    in.close();
                    //设置存入数据库的路径
                    String savePath = "/implMaterial/file/"+code+"/"+ fileName;
                    //经销商号码、名称、路径保存到数据库
                    BizMaterialManage entity = new BizMaterialManage();
                    entity.setCode(code);
                    entity.setName(name);
                    entity.setUploadPerson(username);
                    entity.setImagePath(savePath);
                    entity.setType("2");
                    //保存文件路径到数据库
                    IResult res = bizmaterialmanageService.save(entity);
                    jr.setResult(res);

                } catch (Exception e) {
                    arr.add(i);
                } finally {
                    if (out != null) {
                        out.close();
                        out = null;
                    }

                    if (in != null) {
                        in.close();
                        in = null;
                    }
                }
            } else {
                arr.add(i);
            }
        }
        return jr;
    }
    
    /**
     * 下载
     * @param code
     * @param type
     * @param entity
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @RequestMapping(value="/download/{code}/{type}")
    public void doGet(@PathVariable String code,@PathVariable String type,BizMaterialManage entity,HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
    	// 1.获取需要下载的文件  
    	entity.setCode(code);
        entity.setType(type);
        	//下载文件路径
        String path = PropertiesEnum.getPropertyValue(PropertiesEnum.FILE_UPLOAD_ROOT) + bizmaterialmanageService.getPath(entity);
        File file = new File(path);
        // 取得文件名。
        String filename = file.getName();
    	// 2.通知浏览器以下载方式打开  
    	// 如果文件名中包含中文，则文件名要进行URL编码，URLEncoding.encode;如果不进行编码则文件名显示错误并且不可下载。  
    	response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));  
    	// 3.向浏览器写出数据  
    	FileInputStream in = null;  
    		try {  
    				OutputStream out = response.getOutputStream();  
    				in = new FileInputStream(path);  
    				byte buffer[] = new byte[1024];  
    				int len = 0;  
    		while ((len = in.read(buffer)) > 0) {  
    				out.write(buffer, 0, len);  
    		}  
    	} finally {  
    		if (in != null) {  
    			in.close(); // 关闭流  
    	     }  
    	}  
   }  
    
    /**
     * 批量下载
     * @param code
     * @param type
     * @param entity
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @RequestMapping(value="/batchDownload/{code}/{type}")
    public void batchDownload(@PathVariable String code,@PathVariable String type,BizMaterialManage entity,HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
    	// 1.获取需要下载的文件  
    	entity.setCode(code);
        entity.setType(type);
        	//数据库文件路径
        List<String> paths = bizmaterialmanageService.getPaths(entity);
        //压缩文件 并返回压缩文件路径
        String path = this.compress(paths,code);
        File file = new File(path);
        // 取得文件名。
        String filename = file.getName();
    	// 2.通知浏览器以下载方式打开  
    	// 如果文件名中包含中文，则文件名要进行URL编码，URLEncoding.encode;如果不进行编码则文件名显示错误并且不可下载。  
    	response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));  
    	// 3.向浏览器写出数据  
    	FileInputStream in = null;  
    		try {  
    				OutputStream out = response.getOutputStream();  
    				in = new FileInputStream(path);  
    				byte buffer[] = new byte[1024];  
    				int len = 0;  
    		while ((len = in.read(buffer)) > 0) {  
    				out.write(buffer, 0, len);  
    		}  
    	} finally {  
    		if (in != null) {  
    			in.close(); // 关闭流  
    			//删除生产的zip文件
    			file.delete();
    	     }  
    	}  
   }  
    
    /**
     * 压缩文件
     * @param paths
     * @param code
     * @return
     */
    public String compress(List<String> paths,String code) {
    	String rootPath = PropertiesEnum.getPropertyValue(PropertiesEnum.FILE_UPLOAD_ROOT);
        // 要生成的压缩文件地址和文件名称
        String desPath = rootPath + "/implMaterial/image/"+code+".zip";
        File zipFile = new File(desPath);
        //如果zip文件存在则删除原有的 新建新的zip文件
        if(zipFile.exists()) {
        	zipFile.delete();
        	try {
				zipFile.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
        }
        ZipOutputStream zipStream = null;
        FileInputStream zipSource = null;
        BufferedInputStream bufferStream = null;
        try {
            //构造最终压缩包的输出流
            zipStream = new ZipOutputStream(new FileOutputStream(zipFile));
            for(int i =0;i<paths.size();i++){
            	String path2 = rootPath + paths.get(i);
                File file = new File(path2);
              //将需要压缩的文件格式化为输入流
                zipSource = new FileInputStream(file);
                //压缩条目不是具体独立的文件，而是压缩包文件列表中的列表项，称为条目，就像索引一样
                ZipEntry zipEntry = new ZipEntry(file.getName());
                //定位该压缩条目位置，开始写入文件到压缩包中
                zipStream.putNextEntry(zipEntry);

             //输入缓冲流
             bufferStream = new BufferedInputStream(zipSource, 1024 * 10);
             int read = 0;
             //创建读写缓冲区
             byte[] buf = new byte[1024 * 10];
             while((read = bufferStream.read(buf, 0, 1024 * 10)) != -1)
            {
                zipStream.write(buf, 0, read);
            }

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
                //关闭流
                try {
                    if(null != bufferStream) bufferStream.close();
                    if(null != zipStream) zipStream.close();
                    if(null != zipSource) zipSource.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
        return desPath;
    }
}
